package com.bookrecomm.service.impl;

import com.bookrecomm.dao.TagRepository;
import com.bookrecomm.entity.Tag;
import com.bookrecomm.service.TagService;
import com.bookrecomm.vo.TagVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 标签服务实现类
 * 实现标签相关的业务逻辑
 */
@Service
public class TagServiceImpl implements TagService {

    @Autowired
    private TagRepository tagRepository;

    /**
     * 获取所有标签列表
     * @return 标签列表
     */
    @Override
    public List<TagVO> findAll() {
        List<Tag> tags = tagRepository.findAll();
        return tags.stream()
                .map(this::convertToTagVO)
                .collect(Collectors.toList());
    }

    /**
     * 获取热门标签列表
     * @param limit 限制数量
     * @return 热门标签列表
     */
    @Override
    public List<TagVO> findHotTags(int limit) {
        // 按热度降序排序
        PageRequest pageRequest = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "heat"));
        List<Tag> tags = tagRepository.findAll(pageRequest).getContent();
        
        return tags.stream()
                .map(this::convertToTagVO)
                .collect(Collectors.toList());
    }

    /**
     * 根据ID查询标签
     * @param id 标签ID
     * @return 标签信息
     */
    @Override
    public TagVO findById(Long id) {
        Tag tag = tagRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("标签不存在"));
        return convertToTagVO(tag);
    }

    /**
     * 添加标签
     * @param tag 标签信息
     * @return 添加后的标签信息
     */
    @Override
    @Transactional
    public TagVO addTag(Tag tag) {
        // 检查标签名称是否已存在
        if (tagRepository.existsByName(tag.getName())) {
            throw new RuntimeException("标签名称已存在");
        }
        
        // 设置初始热度
        if (tag.getHeat() == null) {
            tag.setHeat(0);
        }
        
        // 设置状态
        if (tag.getStatus() == null) {
            tag.setStatus(1); // 默认启用
        }
        
        // 设置创建时间和更新时间
        tag.setCreatedAt(LocalDateTime.now());
        tag.setUpdatedAt(LocalDateTime.now());
        
        // 保存标签
        Tag savedTag = tagRepository.save(tag);
        
        return convertToTagVO(savedTag);
    }

    /**
     * 更新标签
     * @param id 标签ID
     * @param tagUpdate 标签信息
     * @return 更新后的标签信息
     */
    @Override
    @Transactional
    public TagVO updateTag(Long id, Tag tagUpdate) {
        Tag tag = tagRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("标签不存在"));
        
        // 检查标签名称是否已存在
        if (tagUpdate.getName() != null && !tagUpdate.getName().equals(tag.getName()) && 
                tagRepository.existsByName(tagUpdate.getName())) {
            throw new RuntimeException("标签名称已存在");
        }
        
        // 更新标签信息
        if (tagUpdate.getName() != null) {
            tag.setName(tagUpdate.getName());
        }
        if (tagUpdate.getDescription() != null) {
            tag.setDescription(tagUpdate.getDescription());
        }
        if (tagUpdate.getHeat() != null) {
            tag.setHeat(tagUpdate.getHeat());
        }
        if (tagUpdate.getStatus() != null) {
            tag.setStatus(tagUpdate.getStatus());
        }
        
        // 更新时间
        tag.setUpdatedAt(LocalDateTime.now());
        
        // 保存标签
        Tag savedTag = tagRepository.save(tag);
        
        return convertToTagVO(savedTag);
    }

    /**
     * 删除标签
     * @param id 标签ID
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public boolean deleteTag(Long id) {
        // 检查标签是否存在
        Tag tag = tagRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("标签不存在"));
        
        // 检查是否有关联的图书
        if (tag.getBooks() != null && !tag.getBooks().isEmpty()) {
            throw new RuntimeException("该标签下有图书，不能删除");
        }
        
        // 删除标签
        tagRepository.deleteById(id);
        
        return true;
    }

    /**
     * 增加标签热度
     * @param id 标签ID
     * @param increment 增量
     * @return 更新后的标签信息
     */
    @Override
    @Transactional
    public TagVO incrementHeat(Long id, Integer increment) {
        Tag tag = tagRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("标签不存在"));
        
        // 增加热度
        tag.setHeat(tag.getHeat() + increment);
        
        // 更新时间
        tag.setUpdatedAt(LocalDateTime.now());
        
        // 保存标签
        Tag savedTag = tagRepository.save(tag);
        
        return convertToTagVO(savedTag);
    }

    /**
     * 将标签实体转换为VO对象
     * @param tag 标签实体
     * @return 标签VO对象
     */
    private TagVO convertToTagVO(Tag tag) {
        TagVO tagVO = new TagVO();
        BeanUtils.copyProperties(tag, tagVO);
        
        // 设置图书数量
        tagVO.setBookCount(tag.getBooks() != null ? (long) tag.getBooks().size() : 0L);
        
        return tagVO;
    }
}
